package service

import (
	"context"
	"database/sql"
	"encoding/json"
	"fx_swift_boss/api"
	"fx_swift_boss/internal/model"
	"fx_swift_boss/pkg/code"
	"fx_swift_boss/pkg/global"
	"fx_swift_boss/pkg/internalerrors"
	"fx_swift_boss/pkg/logger"
	"fx_swift_boss/pkg/page"
	"fx_swift_boss/pkg/utils"
	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/spf13/cast"
	"strings"
)

type IComplySrv interface {
	PostCompanyCustomer(ctx context.Context, req *api.ComplyCompanyOnboardingReq) error
	PostPersonCustomer(ctx context.Context, req *model.ComplyPersonOnboardingReq) error
	CreateCustomerTemp(ctx context.Context, req *api.CustomerTempReq) error
	GetCustomerTemp(ctx context.Context, account, customerId string) (*api.CustomerTempRes, error)
	QueryPersonCustomerList(ctx context.Context, req *api.PersonReq) (*page.Collection[*api.PersonRes], error)
	QueryCompanyCustomerList(ctx context.Context, req *api.CompanyReq) (*page.Collection[*api.CompanyRes], error)
	DoCustomerApproval(ctx context.Context, req *api.DoApprovalReq) error
	GetPaymentInfo(ctx context.Context) ([]*api.PaymentRes, error)
	GetPaymentPurposeInfo(ctx context.Context) ([]*api.PaymentPurposeRes, error)
	GetIncomeSourceInfo(ctx context.Context) ([]*api.IncomeSourceRes, error)
}

type complySrv struct {
}

func NewComplySrv() IComplySrv {
	return &complySrv{}
}

// 获取收入来源
func (c complySrv) GetIncomeSourceInfo(ctx context.Context) ([]*api.IncomeSourceRes, error) {
	var (
		err             error
		incomeSourceObj []*api.IncomeSourceRes
	)

	if err = global.GFDB.Schema("forex").Ctx(ctx).Model("forex_income_source_base").Scan(&incomeSourceObj); err != nil {
		logger.SugarLogger.Error(err)
		return nil, internalerrors.New(code.ErrUnknown, "查询数据报错")
	}
	if incomeSourceObj == nil {
		return []*api.IncomeSourceRes{}, nil
	}
	return incomeSourceObj, err
}

// 获取账户收付款用途
func (c complySrv) GetPaymentPurposeInfo(ctx context.Context) ([]*api.PaymentPurposeRes, error) {
	var (
		err               error
		paymentPurposeObj []*api.PaymentPurposeRes
	)

	if err = global.GFDB.Schema("forex").Ctx(ctx).Model("forex_payment_purpose_base").Scan(&paymentPurposeObj); err != nil {
		logger.SugarLogger.Error(err)
		return nil, internalerrors.New(code.ErrUnknown, "查询数据报错")
	}
	if paymentPurposeObj == nil {
		return []*api.PaymentPurposeRes{}, nil
	}
	return paymentPurposeObj, err
}

// 获取收/付款总额
func (c complySrv) GetPaymentInfo(ctx context.Context) ([]*api.PaymentRes, error) {
	var (
		err        error
		paymentObj []*api.PaymentRes
	)

	if err = global.GFDB.Schema("forex").Ctx(ctx).Model("forex_payment_base").Scan(&paymentObj); err != nil {
		logger.SugarLogger.Error(err)
		return nil, internalerrors.New(code.ErrUnknown, "查询数据报错")
	}
	if paymentObj == nil {
		return []*api.PaymentRes{}, nil
	}
	return paymentObj, err
}

// BOSS端审批下发
func (c complySrv) DoCustomerApproval(ctx context.Context, req *api.DoApprovalReq) error {
	var (
		err         error
		merchantObj *model.ForexOnboardingCustomer
	)
	if err = global.GFDB.Schema("forex").Model("forex_onboarding_customer").
		Where("account=? and customer_id=?", req.Account, req.CustomerId).Scan(&merchantObj); err != nil {
		logger.SugarLogger.Error(err)
		return internalerrors.New(code.ErrUnknown, err.Error())
	}
	if merchantObj == nil {
		return internalerrors.New(code.ErrUnknown, "记录不存在")
	}
	if _, err = global.GFDB.Ctx(ctx).Schema("forex").Model("forex_onboarding_customer").
		Data(g.Map{"customer_status": "REFUSE", "message": req.Message}).Where("account=? and customer_id=?", req.Account, req.CustomerId).Update(); err != nil {
		logger.SugarLogger.Error(err)
		return internalerrors.New(code.ErrUnknown, "更新异常")
	}
	return nil
}

// 获取企业KYC列表
func (c complySrv) QueryCompanyCustomerList(ctx context.Context, req *api.CompanyReq) (*page.Collection[*api.CompanyRes], error) {
	var (
		err        error
		resultList []*api.CompanyRes
		total      int
	)

	collectionDto := &page.Collection[*api.CompanyRes]{}
	collectionDto.Page = req.PageNo
	collectionDto.PageSize = req.PageSize

	mod := global.GFDB.Ctx(ctx).Schema("forex").Model("forex_onboarding_customer foc").
		LeftJoin("forex_agent fa", "foc.account=fa.account").
		LeftJoin("forex_customer_tmp fct", "foc.customer_id=fct.customer_id").
		LeftJoin("forex_company fc", "foc.customer_id=fc.customer_id").
		Fields("foc.customer_id,fa.country,fa.account_type,fa.account,fc.legal_name,foc.created_at,foc.customer_status,foc.message," +
			"foc.overall_level,foc.overall_value," +
			"if(INSTR(fct.req_json,'\"email_address\"'),JSON_UNQUOTE(JSON_EXTRACT(fct.req_json,\"$.internal.step2.legalPerson.contact_information.email_address[0]\")),'') as email")
	if len(req.Name) > 0 {
		mod.Where("fc.legal_name like ?", "%"+req.Name+"%")
	}
	if len(req.Email) > 0 {
		mod.Where("JSON_UNQUOTE(JSON_EXTRACT(fct.req_json,\"$.internal.step2.legalPerson.contact_information.email_address[0]\")) like ?", "%"+req.Email+"%")
	}
	if len(req.StartTime) > 0 {
		mod.Where("foc.created_at>=?", req.StartTime+" 00:00:00")
	}
	if len(req.EndTime) > 0 {
		mod.Where("foc.created_at<=?", req.EndTime+" 23:59:59")
	}
	mod.Where("fa.account_type=?", "01")
	if len(req.SortFields) > 0 && len(req.SortMethod) > 0 {
		mod.Order(req.SortFields + " " + req.SortMethod)
	}

	mod.Order("foc.created_at desc")
	mod.Limit(int(page.PageToOffset(req.PageNo, req.PageSize)), cast.ToInt(req.PageSize))
	err = mod.ScanAndCount(&resultList, &total, false)
	collectionDto.TotalPage = page.GetTotalPage(req.PageNo, req.PageSize, cast.ToInt64(total))

	if err != nil {
		return nil, internalerrors.New(code.ErrUnknown, "数据查询异常")
	}
	//TODO 获取账户余额、交易笔数

	collectionDto.Total = cast.ToInt64(total)
	collectionDto.List = resultList

	return collectionDto, err
}

// 获取KYC列表
func (c complySrv) QueryPersonCustomerList(ctx context.Context, req *api.PersonReq) (*page.Collection[*api.PersonRes], error) {
	var (
		err        error
		resultList []*api.PersonRes
		total      int
	)

	collectionDto := &page.Collection[*api.PersonRes]{}
	collectionDto.Page = req.PageNo
	collectionDto.PageSize = req.PageSize

	mod := global.GFDB.Ctx(ctx).Schema("forex").Model("forex_onboarding_customer foc").
		LeftJoin("forex_agent fa", "foc.account=fa.account").
		LeftJoin("forex_person fp", "foc.customer_id=fp.customer_id").
		Fields("foc.customer_id,fa.country,fa.account_type,fa.account,fa.email,fp.first_name,fp.middle_name,fp.last_name,foc.created_at,foc.customer_status,foc.message," +
			"foc.overall_level,foc.overall_value")
	if len(req.Name) > 0 {
		mod.Where("concat(fp.last_name,fp.middle_name,fp.first_name) like ?", "%"+req.Name+"%")
	}
	if len(req.Email) > 0 {
		mod.Where("fa.email like ?", "%"+req.Email+"%")
	}
	if len(req.Country) > 0 {
		mod.Where("fa.country=?", req.Country)
	}
	if len(req.StartTime) > 0 {
		mod.Where("foc.created_at>=?", req.StartTime+" 00:00:00")
	}
	if len(req.EndTime) > 0 {
		mod.Where("foc.created_at<=?", req.EndTime+" 23:59:59")
	}
	mod.Where("fa.account_type=?", "00")
	if len(req.SortFields) > 0 && len(req.SortMethod) > 0 {
		mod.Order(req.SortFields + " " + req.SortMethod)
	}

	mod.Order("foc.created_at desc")
	mod.Limit(int(page.PageToOffset(req.PageNo, req.PageSize)), cast.ToInt(req.PageSize))
	err = mod.ScanAndCount(&resultList, &total, false)
	collectionDto.TotalPage = page.GetTotalPage(req.PageNo, req.PageSize, cast.ToInt64(total))

	if err != nil {
		return nil, internalerrors.New(code.ErrUnknown, "数据查询异常")
	}
	//TODO 获取账户余额、交易笔数

	collectionDto.Total = cast.ToInt64(total)
	collectionDto.List = resultList

	return collectionDto, err
}

// 获取KYC临时资料
func (c complySrv) GetCustomerTemp(ctx context.Context, acct, custId string) (*api.CustomerTempRes, error) {
	var (
		err        error
		account    string
		customerId string
		reqJsonObj *api.CustomerTempRes
	)

	if acct != "" {
		account = acct
	}
	if custId != "" {
		customerId = custId
	}
	if err = global.GFDB.Ctx(ctx).Schema("forex").Model("forex_customer_tmp").Where("account=? and customer_id=?", account, customerId).
		Scan(&reqJsonObj); err != nil {
		return nil, internalerrors.New(code.ErrUnknown, err.Error())
	}
	if reqJsonObj == nil {
		return &api.CustomerTempRes{}, nil
	}
	return &api.CustomerTempRes{
		Account:    reqJsonObj.Account,
		ReqJson:    reqJsonObj.ReqJson,
		CustomerId: reqJsonObj.CustomerId,
	}, err
}

// KYC认证资料临时保存
func (c complySrv) CreateCustomerTemp(ctx context.Context, req *api.CustomerTempReq) error {
	var (
		err        error
		reqJsonObj []*model.ForexCustomerTmp
		result     sql.Result
		rowsNums   int64
	)

	mod := global.GFDB.Schema("forex").Ctx(ctx).Model("forex_customer_tmp")
	if req.CustomerId != "" {
		mod.Where("customer_id=?", req.CustomerId)
	}
	if req.Account != "" {
		mod.Where("account=?", req.Account)
	}
	err = mod.Scan(&reqJsonObj)
	if len(reqJsonObj) == 0 {
		result, err = global.GFDB.Schema("forex").Insert(ctx, "forex_customer_tmp", &model.ForexCustomerTmp{
			Account:    req.Account,
			ReqJson:    req.ReqJson,
			CustomerId: req.CustomerId,
		})

		if err != nil {
			logger.SugarLogger.Error(err)
			return internalerrors.New(code.ErrUnknown, "kyc认证资料写入异常")
		}
		rowsNums, err = result.RowsAffected()
		if err != nil || rowsNums == 0 {
			logger.SugarLogger.Error(err)
			return internalerrors.New(code.ErrUnknown, "kyc认证资料写入异常")
		}
	} else {
		if req.AccountType == "00" {
			if req.ReqJson != "" {
				result, err = global.GFDB.Ctx(ctx).Schema("forex").Model("forex_customer_tmp").
					Data(g.Map{"req_json": req.ReqJson}).Where("account=?", req.Account).Update()
			} else {
				result, err = global.GFDB.Ctx(ctx).Schema("forex").Model("forex_customer_tmp").
					Data(g.Map{"customer_id": req.CustomerId}).Where("account=?", req.Account).Update()
			}
		} else {
			if req.CustomerId == "" {
				result, err = global.GFDB.Schema("forex").Insert(ctx, "forex_customer_tmp", &model.ForexCustomerTmp{
					Account:    req.Account,
					ReqJson:    req.ReqJson,
					CustomerId: req.CustomerId,
				})
			} else {
				if req.ReqJson != "" {
					result, err = global.GFDB.Ctx(ctx).Schema("forex").Model("forex_customer_tmp").
						Data(g.Map{"req_json": req.ReqJson}).Where("account=? and customer_id=?", req.Account, req.CustomerId).Update()
				} else {
					result, err = global.GFDB.Ctx(ctx).Schema("forex").Model("forex_customer_tmp").
						Data(g.Map{"customer_id": req.CustomerId}).Where("account=? and customer_id=?", req.Account, req.CustomerId).Update()
				}
			}
		}
		if err != nil {
			logger.SugarLogger.Error(err)
			return internalerrors.New(code.ErrUnknown, "kyc认证资料更新异常")
		}
		rowsNums, err = result.RowsAffected()
		if err != nil || rowsNums == 0 {
			logger.SugarLogger.Error(err)
			return internalerrors.New(code.ErrUnknown, "kyc认证资料更新异常")
		}
	}

	return err
}

// 提交企业kyc资料
func (c complySrv) PostCompanyCustomer(ctx context.Context, req *api.ComplyCompanyOnboardingReq) error {
	var (
		err                       error
		customerResult            []*model.ForexOnboardingCustomer
		customerId                string
		worklowInstanceIdentifier string
	)

	if !utils.IsEmptyStruct(req.Customer.Company) && req.Customer.Company.LegalName == "" {
		return internalerrors.New(code.ErrUnknown, "LegalName不能为空")
	}
	account := req.Account
	accountType := req.AccountType
	customerId = utils.GenerateCode64()
	if err = global.GFDB.Schema("forex").Model("forex_onboarding_customer").
		Where("account=?", account).Scan(&customerResult); err != nil {
		logger.SugarLogger.Error(err)
		return internalerrors.New(code.ErrUnknown, err.Error())
	}
	if len(customerResult) != 0 {
		if accountType == "00" {
			//个人kyc
			if customerResult[0].CustomerStatus == "COMPLETED" {
				return internalerrors.New(code.ErrUnknown, "已有入职调查记录")
			} else {
				customerId = req.Customer.CustomerId
			}
		} else {
			//企业kyc
			if req.Customer.CustomerId != "" {
				customerId = req.Customer.CustomerId
			}
		}
	}

	//提交客户记录到comply进行入职调查
	worklowInstanceIdentifier, err = DoPostCompanyComply(ctx, req)
	if err != nil {
		logger.SugarLogger.Error(err)
		return internalerrors.New(code.ErrUnknown, err.Error())
	}

	db := g.DB()
	err = db.Schema("forex").Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		//company入库
		if !utils.IsEmptyStruct(req.Customer.Company) {
			compayList := []*model.ForexCompany{}
			companyObj := &model.ForexCompany{}
			companyObj.CustomerId = customerId
			companyObj.CompanyStatus = req.Customer.Company.CompanyStatus
			if len(req.Customer.Company.Aliases) != 0 {
				companyObj.Aliases = strings.Join(req.Customer.Company.Aliases, ";")
			}
			companyObj.CompanyType = req.Customer.Company.CompanyType
			companyObj.LegalName = req.Customer.Company.LegalName
			companyObj.PlaceOfRegistration = req.Customer.Company.PlaceOfRegistration
			companyObj.RegistrationAuthorityIdentification = req.Customer.Company.RegistrationAuthorityIdentification
			if !utils.IsEmptyStruct(req.Customer.Company.IncorporationDate) {
				inDate, _ := json.Marshal(req.Customer.Company.IncorporationDate)
				companyObj.IncorporationDate = string(inDate)
			}
			if len(req.Customer.Company.Addresses) != 0 {
				address, _ := json.Marshal(req.Customer.Company.Addresses)
				companyObj.Addresses = string(address)
			}
			compayList = append(compayList, companyObj)
			//先删除
			result, err := global.GFDB.Schema("forex").Model("forex_company").Where("customer_id", customerId).Delete()
			if err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "company资料删除失败")
			}
			//后插入
			result, err = tx.Model("forex_company").Data(compayList).Insert()

			if err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "company资料插入失败")
			}
			rowsNums, err := result.RowsAffected()
			if err != nil || rowsNums == 0 {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "company资料插入失败")
			}
		}
		//customer主表入库
		if !utils.IsEmptyStruct(req.Customer) {
			customerList := []*model.ForexOnboardingCustomer{}
			customerObj := &model.ForexOnboardingCustomer{}
			customerObj.CustomerId = customerId
			customerObj.Account = account
			if !utils.IsEmptyStruct(req.Customer.ExternalIdentifier) {
				externalId, _ := json.Marshal(req.Customer.ExternalIdentifier)
				customerObj.ExternalIdentifier = string(externalId)
			}
			customerObj.WorkflowInstanceIdentifier = worklowInstanceIdentifier
			//var customerStatus = "APPROVAL"
			//if customerResult != nil {
			customerObj.CustomerStatus = customerResult[0].CustomerStatus
			if req.Configuration.ScreeningConfigurationIdentifier != "" || req.Configuration.MonitorConfigurationIdentifier != "" {
				config, _ := json.Marshal(req.Configuration)
				customerObj.Configuration = string(config)
			}
			customerObj.CustomerIdentifier = ""
			customerObj.ScreeningResult = ""
			customerObj.OverallValue = ""
			customerObj.OverallLevel = ""
			//}
			customerList = append(customerList, customerObj)

			//先删除
			result, err := global.GFDB.Schema("forex").Model("forex_onboarding_customer").Where("customer_id", customerId).Delete()
			if err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "customer资料删除失败")
			}
			//后插入
			result, err = tx.Model("forex_onboarding_customer").Data(customerList).Insert()

			if err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "customer资料插入失败")
			}
			rowsNums, err := result.RowsAffected()
			if err != nil || rowsNums == 0 {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "customer资料插入失败")
			}
		}

		//product入库
		if len(req.Product) != 0 {
			productList := []*model.ForexProduct{}
			for _, value := range req.Product {
				productObj := &model.ForexProduct{}
				productObj.CustomerId = customerId
				productObj.ProductName = value.ProductName
				productObj.ProductStatus = value.ProductStatus
				productObj.Currency = value.Currency
				productObj.MonthlyPaymentValue = value.MonthlyPaymentValue
				productObj.MonthlyReceivedValue = value.MonthlyReceivedValue
				productObj.MonthlyTransactionNumber = value.MonthlyTransactionNumber
				productObj.Purpose = value.Purpose
				if !utils.IsEmptyStruct(value.ProductDetails) {
					details, _ := json.Marshal(value.ProductDetails)
					productObj.ProductDetails = string(details)
				}
				if !utils.IsEmptyStruct(value.OnboardingChannel) {
					channel, _ := json.Marshal(value.OnboardingChannel)
					productObj.OnboardingChannel = string(channel)
				}
				productList = append(productList, productObj)
			}
			//先删除
			result, err := global.GFDB.Schema("forex").Model("forex_product").Where("customer_id", customerId).Delete()
			if err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "product资料删除失败")
			}
			//后插入
			result, err = tx.Model("forex_product").Data(productList).Insert()

			if err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "product资料插入失败")
			}
			rowsNums, err := result.RowsAffected()
			if err != nil || rowsNums == 0 {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "product资料插入失败")
			}
		}
		return nil
	})
	if err != nil {
		logger.SugarLogger.Error("KYC事务执行出错", err)
		return internalerrors.New(code.ErrUnknown, "KYC资料录入失败")
	} else {
		logger.SugarLogger.Info("KYC事务执行成功")
	}
	//对kyc资料进行临时备份，以便入库失败进行补数据
	customerTmp := &api.CustomerTempReq{
		Account:     account,
		AccountType: "01",
		CustomerId:  customerId,
	}
	err = c.CreateCustomerTemp(ctx, customerTmp)
	if err != nil {
		logger.SugarLogger.Error("kyc资料备份失败", err)
	}

	return nil
}

// 提交个人kyc资料
func (c complySrv) PostPersonCustomer(ctx context.Context, req *model.ComplyPersonOnboardingReq) error {
	var (
		err                       error
		customerResult            []*model.ForexOnboardingCustomer
		customerId                string
		worklowInstanceIdentifier string
	)

	if req.Customer.Person.PersonalIdentification[0].DocumentIdentifier == "" {
		return internalerrors.New(code.ErrUnknown, "DocumentIdentifier证件号不能为空")
	}
	if req.Customer.Person.LastName == "" {
		return internalerrors.New(code.ErrUnknown, "LastName不能为空")
	}
	account := req.Account
	accountType := req.AccountType
	customerId = utils.GenerateCode64()
	if err = global.GFDB.Schema("forex").Model("forex_onboarding_customer").
		Where("account=?", account).Scan(&customerResult); err != nil {
		logger.SugarLogger.Error(err)
		return internalerrors.New(code.ErrUnknown, err.Error())
	}
	if len(customerResult) != 0 {
		if accountType == "00" {
			//个人kyc
			if customerResult[0].CustomerStatus == "COMPLETED" {
				return internalerrors.New(code.ErrUnknown, "已有入职调查记录")
			} else {
				customerId = req.Customer.CustomerId
			}
		} else {
			//企业kyc
			if req.Customer.CustomerId != "" {
				customerId = req.Customer.CustomerId
			}
		}
	}

	//提交客户记录到comply进行入职调查
	worklowInstanceIdentifier, err = DoPostPersonComply(ctx, req)
	if err != nil {
		logger.SugarLogger.Error(err)
		return internalerrors.New(code.ErrUnknown, err.Error())
	}

	db := g.DB()
	err = db.Schema("forex").Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		//person入库
		if !utils.IsEmptyStruct(req.Customer.Person) {
			personList := []*model.ForexPerson{}
			personObj := &model.ForexPerson{}
			personObj.CustomerId = customerId
			personObj.FirstName = req.Customer.Person.FirstName
			personObj.LastName = req.Customer.Person.LastName
			personObj.MiddleName = req.Customer.Person.MiddleName
			personObj.Gender = req.Customer.Person.Gender
			if req.Customer.Person.Nationality != nil {
				personObj.Nationality = strings.Join(req.Customer.Person.Nationality, ";")
			}
			personObj.Title = req.Customer.Person.Title
			if len(req.Customer.Person.Address) != 0 {
				addStr, _ := json.Marshal(req.Customer.Person.Address)
				personObj.Address = string(addStr)
			}
			if !utils.IsEmptyStruct(req.Customer.Person.DateOfBirth) {
				dateOfBirth, _ := json.Marshal(req.Customer.Person.DateOfBirth)
				personObj.DateOfBirth = string(dateOfBirth)
			}
			if !utils.IsEmptyStruct(req.Customer.Person.ContactInformation) {
				contactInfo, _ := json.Marshal(req.Customer.Person.ContactInformation)
				personObj.ContactInformation = string(contactInfo)
			}
			personObj.CountryOfBirth = req.Customer.Person.CountryOfBirth
			if len(req.Customer.Person.PersonalIdentification) != 0 {
				personIdentification, _ := json.Marshal(req.Customer.Person.PersonalIdentification)
				personObj.PersonalIdentification = string(personIdentification)
			}
			if req.Customer.Person.Profession != nil {
				personObj.Profession = strings.Join(req.Customer.Person.Profession, ";")
			}
			if len(req.Customer.Person.ResidentialInformation) != 0 {
				residentialInfo, _ := json.Marshal(req.Customer.Person.ResidentialInformation)
				personObj.ResidentialInformation = string(residentialInfo)
			}
			personObj.SalaryCurrency = req.Customer.Person.SalaryCurrency
			if !utils.IsEmptyStruct(req.Customer.Person.SalaryRange) {
				salaryRange, _ := json.Marshal(req.Customer.Person.SalaryRange)
				personObj.SalaryRange = string(salaryRange)
			}
			personObj.SourceOfWealth = req.Customer.Person.SourceOfWealth
			personList = append(personList, personObj)

			//先删除
			result, err := global.GFDB.Schema("forex").Model("forex_person").Where("customer_id", customerId).Delete()
			if err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "person资料删除失败")
			}
			//后插入
			result, err = tx.Model("forex_person").Data(personList).Insert()

			if err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "person资料插入失败")
			}
			rowsNums, err := result.RowsAffected()
			if err != nil || rowsNums == 0 {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "person资料插入失败")
			}
		}
		//customer主表入库
		if !utils.IsEmptyStruct(req.Customer) {
			customerList := []*model.ForexOnboardingCustomer{}
			customerObj := &model.ForexOnboardingCustomer{}
			customerObj.CustomerId = customerId
			customerObj.Account = account
			if !utils.IsEmptyStruct(req.Customer.ExternalIdentifier) {
				externalId, _ := json.Marshal(req.Customer.ExternalIdentifier)
				customerObj.ExternalIdentifier = string(externalId)
			}
			customerObj.WorkflowInstanceIdentifier = worklowInstanceIdentifier
			//var customerStatus = "APPROVAL"
			//if customerResult != nil {
			customerObj.CustomerStatus = customerResult[0].CustomerStatus
			if req.Configuration.ScreeningConfigurationIdentifier != "" || req.Configuration.MonitorConfigurationIdentifier != "" {
				config, _ := json.Marshal(req.Configuration)
				customerObj.Configuration = string(config)
			}
			customerObj.CustomerIdentifier = ""
			customerObj.ScreeningResult = ""
			customerObj.OverallValue = ""
			customerObj.OverallLevel = ""
			//}
			customerList = append(customerList, customerObj)

			//先删除
			result, err := global.GFDB.Schema("forex").Model("forex_onboarding_customer").Where("customer_id", customerId).Delete()
			if err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "customer资料删除失败")
			}
			//后插入
			result, err = tx.Model("forex_onboarding_customer").Data(customerList).Insert()

			if err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "customer资料插入失败")
			}
			rowsNums, err := result.RowsAffected()
			if err != nil || rowsNums == 0 {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "customer资料插入失败")
			}
		}

		//product入库
		if len(req.Product) != 0 {
			productList := []*model.ForexProduct{}
			for _, value := range req.Product {
				productObj := &model.ForexProduct{}
				productObj.CustomerId = customerId
				productObj.ProductName = value.ProductName
				productObj.ProductStatus = value.ProductStatus
				productObj.Currency = value.Currency
				productObj.MonthlyPaymentValue = value.MonthlyPaymentValue
				productObj.MonthlyReceivedValue = value.MonthlyReceivedValue
				productObj.MonthlyTransactionNumber = value.MonthlyTransactionNumber
				productObj.Purpose = value.Purpose
				if !utils.IsEmptyStruct(value.ProductDetails) {
					details, _ := json.Marshal(value.ProductDetails)
					productObj.ProductDetails = string(details)
				}
				if !utils.IsEmptyStruct(value.OnboardingChannel) {
					channel, _ := json.Marshal(value.OnboardingChannel)
					productObj.OnboardingChannel = string(channel)
				}
				productList = append(productList, productObj)
			}
			//先删除
			result, err := global.GFDB.Schema("forex").Model("forex_product").Where("customer_id", customerId).Delete()
			if err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "product资料删除失败")
			}
			//后插入
			result, err = tx.Model("forex_product").Data(productList).Insert()

			if err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "product资料插入失败")
			}
			rowsNums, err := result.RowsAffected()
			if err != nil || rowsNums == 0 {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "product资料插入失败")
			}
		}
		return nil
	})
	if err != nil {
		logger.SugarLogger.Error("KYC事务执行出错", err)
		return internalerrors.New(code.ErrUnknown, "KYC资料录入失败")
	} else {
		logger.SugarLogger.Info("KYC事务执行成功")
	}
	//对kyc资料进行临时备份，以便入库失败进行补数据
	customerTmp := &api.CustomerTempReq{
		Account:     account,
		AccountType: "00",
		CustomerId:  customerId,
	}
	err = c.CreateCustomerTemp(ctx, customerTmp)
	if err != nil {
		logger.SugarLogger.Error("kyc资料备份失败", err)
	}

	return nil
}
